package com.grace.common;

import com.grace.exception.ParamException;
import com.grace.exception.PermissionException;
import com.sun.corba.se.spi.presentation.rmi.StubAdapter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 全局异常捕获类
 */
@Slf4j
//切记需要去spring里面配置一下这个bean，被spring管理，为什么不用注解。。
public class SpringExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception ex) {
        //获取请求URL
        String url = request.getRequestURL().toString();
        ModelAndView mv;
        String defaultMsg = "system error";
        //接下来我们需要对两种请求做一些处理，如何判断是数据请求还是页面请求呢？
        //提供两种方案：
        //方案一：是我们从request里面，取出当前提交请求的header，看header里面属于正常文本请求还是页面请求（复杂）
        //方案二：我们直接通过接口，比如我们定义一下所有数据请求为.json结尾，页面请求为.page结尾
        //这样只要根据它的请求来判断它的后缀就可以了（两个好处，看完接口后，根据这个接口名称，
        // 我们就知道当前是json请求还是页面请求。像其它jsp页面，按照自己的请求规则就好了）

        //这里我们要求项目所有请求json数据，都使用.json结尾
        //endsWith获取后缀
        if (url.endsWith(".json")) {    //json异常处理
            if (ex instanceof PermissionException || ex instanceof ParamException) { //如果我当前的异常是我自己定义的异常的话
                JsonData result = JsonData.fail(ex.getMessage()); //msg就要使用我们抛出来的msg
                //为什么这里使用toMap()方法，因为mv允许你传一个map的一个值
                //为了保证异常返回结果和正常返回结果一致，我们把当前的JsonData和之前结果返回值一样的一个结果
                //为什么叫jsonView，因为在springmvc的配置中定义过jsonView
                //做成json返回的
                mv = new ModelAndView("jsonView", result.toMap());
            } else {
                //未知异常
                log.error("unknown json Exception, url:" + url, ex);
                JsonData result = JsonData.fail(defaultMsg);
                mv = new ModelAndView("jsonView", result.toMap());
            }
            //这里我们要求项目所有请求page数据，都使用.page结尾
        } else if (url.endsWith(".page")) {    //page异常处理
            log.error("unknown page Exception, url:" + url, ex);
            JsonData result = JsonData.fail(ex.getMessage());
            //定义exception会怎么样呢？它会和普通的展示页面一样，会去找一个exception.jsp
            //需要我们补充一个exception
            mv = new ModelAndView("exception", result.toMap());
        } else { //页面请求（全局处理）
            //未知异常
            log.error("unknown unknown Exception, url:" + url, ex);
            JsonData result = JsonData.fail(ex.getMessage());
            mv = new ModelAndView("jsonView", result.toMap()); //这里为什么不用改成exception
        }


        return mv;
    }
}
